package per.hx.bs.sys.serviceimpl;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.ArrayUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import per.hx.bs.base.domain.ReturnDTO;
import per.hx.bs.base.domain.Tree;

import per.hx.bs.common.config.HuXingBsConfig;

import per.hx.bs.constant.Setting;
import per.hx.bs.sys.dao.SysDeptDao;
import per.hx.bs.sys.dao.SysFileDao;
import per.hx.bs.sys.dao.SysUserDao;
import per.hx.bs.sys.dao.SysUserRoleDao;

import per.hx.bs.entity.sys.SysDeptDO;
import per.hx.bs.entity.sys.SysUserDO;
import per.hx.bs.entity.sys.SysUserRoleDO;
import per.hx.bs.util.*;


import per.hx.bs.vo.SysUserVo;

import java.util.*;


/**
 * @author HuXing
 * @date 2018/2/26  10:41
 */

@Transactional(rollbackFor = Exception.class)
@RestController
@RequestMapping(value = "sys-service/user")
public class SysUserApiServiceImpl {

    private final
    SysUserDao sysUserDao;
    private final
    SysUserRoleDao sysUserRoleDao;
    private final
    SysDeptDao sysDeptDao;

    @Autowired
    public SysUserApiServiceImpl(SysUserDao sysUserDao, SysUserRoleDao sysUserRoleDao, SysDeptDao sysDeptDao) {
        this.sysUserDao = sysUserDao;
        this.sysUserRoleDao = sysUserRoleDao;
        this.sysDeptDao = sysDeptDao;
    }

    /**
     * 用户登录
     *
     * @param loginName 登录名称
     * @return 登录用户
     */
    @GetMapping(value = "/login")
    public SysUserDO userLogin(@RequestParam("loginName") String loginName) {

        SysUserDO userDO = sysUserDao.selectOne(new SysUserDO(loginName));
        if (userDO != null) {
            List<Long> roleIds = sysUserRoleDao.listRolesId(userDO.getUserId());
            userDO.setRoleIds(roleIds);
        }
        return userDO;
    }

    /**
     * 通过id获取用户信息
     *
     * @param userId 用户Id
     * @return 用户信息
     */

    @GetMapping(value = "/{userId}")
    public SysUserDO selectOneById(@PathVariable("userId") Long userId) {
        List<Long> roleIds = sysUserRoleDao.listRolesId(userId);
        SysUserDO sysUserDO = sysUserDao.selectById(userId);
        sysUserDO.setRoleIds(roleIds);
        return sysUserDO;
    }

    /**
     * 按条件查询用户信息
     *
     * @param map 条件
     * @return 用户信息
     */
    @PostMapping(value = "/users")
    public List<SysUserDO> list(@RequestBody Map<String, Object> map) {

        return sysUserDao.listUser(map);
    }

    /**
     * 按条件统计
     *
     * @param map 条件
     * @return 用户信息
     */
    @PostMapping(value = "/count")
    public int count(@RequestBody Map<String, Object> map) {
        return sysUserDao.countUser(map);
    }

    /**
     * 添加用户信息
     *
     * @param sysUserDO 用户信息
     * @return 影响的行数
     */
    @PostMapping(value = "/save")
    public int save(@RequestBody SysUserDO sysUserDO) {

        int count = sysUserDao.insert(sysUserDO);
        Long userId = sysUserDO.getUserId();
        List<Long> roles = sysUserDO.getRoleIds();
        sysUserRoleDao.deleteByUserId(userId);
        List<SysUserRoleDO> list = new ArrayList<SysUserRoleDO>();
        setUserRole(userId, roles, list);
        if (!list.isEmpty()) {
            sysUserRoleDao.batchInsert(list);
        }
        return count;
    }

    /**
     * 修改用户信息
     *
     * @param sysUserDO 用户信息
     * @return 影响的行数
     */
    @PutMapping(value = "/update")
    public int update(@RequestBody SysUserDO sysUserDO) {
        int count = sysUserDao.updateById(sysUserDO);

        Long userId = sysUserDO.getUserId();
        List<Long> roles = sysUserDO.getRoleIds();
        List<SysUserRoleDO> list = new ArrayList<SysUserRoleDO>();
        setUserRole(userId, roles, list);
        if (!list.isEmpty()) {
            sysUserRoleDao.deleteByUserId(userId);
            sysUserRoleDao.batchInsert(list);
        }
        return count;
    }

    private void setUserRole(Long userId, List<Long> roles, List<SysUserRoleDO> list) {
        if (roles != null && !roles.isEmpty()) {
            for (Long roleId : roles) {
                SysUserRoleDO sur = new SysUserRoleDO();
                sur.setUserId(userId);
                sur.setRoleId(roleId);
                list.add(sur);
            }
        }
    }

    /**
     * 删除用户信息
     *
     * @param userId 用户id
     * @return 影响的行数
     */
    @DeleteMapping(value = "/delete")
    public int remove(@RequestParam("userId") long userId) {
        sysUserRoleDao.deleteByUserId(userId);
        return sysUserDao.deleteById(userId);
    }

    /**
     * 批量删除
     *
     * @param userIds 用户ids
     * @return 影响的行数
     */
    @DeleteMapping(value = "/deletes")
    public int batchRemove(@RequestParam("userIds") Long[] userIds) {
        int count = sysUserDao.deleteBatchIds(Arrays.asList(userIds));
        sysUserRoleDao.deleteBatchUserIds(Arrays.asList(userIds));
        return count;
    }

    /**
     * 检查用户是否可用
     *
     * @param params 检查条件
     * @return 是否
     */
    @PostMapping(value = "/exit")
    public boolean exit(@RequestBody Map<String, Object> params) {
        boolean exit;
        exit = sysUserDao.listUser(params).size() > 0;
        return exit;
    }

    /**
     * 修改用户密码
     *
     * @param sysUserVo 用户信息
     * @return 影响行数
     */
    @PutMapping(value = "/resetPwd")
    public ReturnDTO resetPwd(@RequestBody SysUserVo sysUserVo) {
        try {
            SysUserDO sysUserDO = sysUserVo.getSysUserDO();
            sysUserDO.setPassword(PasswordUtils.entryptPassword(sysUserVo.getPwdNew()));
            if (sysUserDao.updateById(sysUserDO) > 0) {
                return ReturnDTO.ok();
            } else {
                return ReturnDTO.error();
            }
        } catch (RuntimeException e) {
            return ReturnDTO.error(e.getMessage());
        }
    }

    /**
     * 重置密码
     *
     * @param sysUserVo 用户信息
     * @return 影响的行数
     */
    @PutMapping(value = "/adminResetPwd")
    public int adminResetPwd(@RequestBody SysUserVo sysUserVo) {
        SysUserDO sysUserDO = sysUserVo.getSysUserDO();
        sysUserDO.setPassword(PasswordUtils.entryptPassword(sysUserVo.getPwdNew()));
        return sysUserDao.updateById(sysUserDO);
    }

    /**
     * 修改用户信息
     *
     * @param sysUserDO 用户信息
     * @return 影响的行数
     */
    @PutMapping(value = "/updatePersonal")
    public int updatePersonal(@RequestBody SysUserDO sysUserDO) {
        return sysUserDao.updateById(sysUserDO);
    }

    /**
     * 获取用户树形列表
     *
     * @return 树
     */
    @PutMapping(value = "/tree")
    public String getTree(@RequestBody Map<String, Object> map) {
        if (map.size() == 0) {
            map.put("roleSign", Setting.ROLE_USER_SIGN_T);
        }
        List<Tree<SysDeptDO>> trees = new ArrayList<Tree<SysDeptDO>>();
        List<SysDeptDO> depts = sysDeptDao.selectByMap(new HashMap<String, Object>(0));
        Long[] pDepts = sysDeptDao.listParentDept().toArray(new Long[0]);
        Long[] uDepts = sysUserDao.listAllDept().toArray(new Long[0]);
        Long[] allDepts = (Long[]) ArrayUtils.addAll(pDepts, uDepts);
        for (SysDeptDO dept : depts) {
            if (!ArrayUtils.contains(allDepts, dept.getDeptId())) {
                continue;
            }
            Tree<SysDeptDO> tree = new Tree<SysDeptDO>();
            tree.setId(dept.getDeptId().toString());
            tree.setParentId(dept.getParentId().toString());
            tree.setText(dept.getName());
            Map<String, Object> state = new HashMap<String, Object>(16);
            state.put("opened", true);
            state.put("mType", "dept");
            tree.setState(state);
            trees.add(tree);
        }
        List<SysUserDO> users = sysUserDao.selectTreeByMap(map);
        for (SysUserDO user : users) {
            Tree<SysDeptDO> tree = new Tree<SysDeptDO>();
            tree.setId(user.getUserId().toString());
            tree.setParentId(user.getDeptId().toString());
            tree.setText(user.getName());
            Map<String, Object> state = new HashMap<String, Object>(16);
            state.put("opened", true);
            state.put("mType", "user");
            tree.setState(state);
            trees.add(tree);
        }
        return JSON.toJSONString(BuildTree.build(trees, null));
    }

    /**
     * 通过ids 批量获取用户信息
     *
     * @param ids 用户id
     * @return 用户
     */
    @PostMapping(value = "/ids")
    public List<SysUserDO> selectByIds(@RequestBody Long[] ids) {
        return sysUserDao.selectBatchIds(Arrays.asList(ids));
    }
}
